package com.myl.generator.service;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;

import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;

import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.myl.core.basic.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * GeneratorService
 * author: myl <ixiaomu@qq.com> 2024/1/5
 * tips:
 */
@Slf4j
@Service
public class GeneratorService {

    @Value("${spring.datasource.url}")
    protected String dbUrl;

    @Value("${spring.datasource.username}")
    protected String username;

    @Value("${spring.datasource.password}")
    protected String password;

    /**
     * 数据源配置
     */
    protected DataSourceConfig dataSourceConfig() {
        return new DataSourceConfig
                .Builder(dbUrl, username, password)
                .build();
    }

    /**
     * 生成代码
     *
     * @param tableNames String...
     */
    public void doGenerator(String... tableNames) {
        //
        new AutoGenerator(dataSourceConfig())
                .strategy(strategyConfig(tableNames).build())
                .global(globalConfig().build())
                .injection(injectionConfig().build())
                // 包配置
                .packageInfo(packageConfig().build())
                // 模板配置
                .template(templateConfig().build())
                .execute();
    }

    /**
     * 执行数据库脚本
     */
    protected static void initDataSource(DataSourceConfig dataSourceConfig) throws SQLException {

    }

    /**
     * 策略配置
     */
    protected static StrategyConfig.Builder strategyConfig(String... tableNames) {
        StrategyConfig.Builder builder = new StrategyConfig.Builder();
        builder.addInclude(tableNames)
                .addTablePrefix(new String[]{"myl_"})
                // Entity
                .entityBuilder()
                .superClass("com.myl.core.basic.BaseEntity")
                .enableChainModel()
                .enableLombok()
                .enableTableFieldAnnotation()
                .naming(NamingStrategy.underline_to_camel)
                .columnNaming(NamingStrategy.underline_to_camel)
                .logicDeleteColumnName("is_deleted")
                .addSuperEntityColumns("id", "create_time", "update_time", "is_deleted", "status")
                .addTableFills(new Column("createTime", FieldFill.INSERT))
                .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
                .idType(IdType.AUTO)
                .enableFileOverride()
                // Mapper
                .mapperBuilder()
                // Service
                .serviceBuilder()
                .enableFileOverride()
                // 控制器
                .controllerBuilder()
                .superClass(BaseController.class)
                .enableHyphenStyle()
                .enableRestStyle()
                .enableFileOverride();
        return builder;

    }

    /**
     * 全局配置
     */
    protected static GlobalConfig.Builder globalConfig() {
        return new GlobalConfig.Builder()
                .author("Myl <ixiaomu@qq.com>")
                .enableSpringdoc()
                .commentDate("yyyy-MM-dd HH:mm")
                .outputDir("autocode")
                .disableOpenDir();
    }

    /**
     * 包配置
     */
    protected static PackageConfig.Builder packageConfig() {
        return new PackageConfig.Builder()
                .parent("com")
                .moduleName("myl")
                .controller("admin.controller")
                .serviceImpl("admin.service.impl")
                .service("admin.service")
                .mapper("core.mapper")
                .entity("core.domain.entity")
                .xml("mapper.xml")
                .pathInfo(Collections.singletonMap(OutputFile.xml, "autocode/mapper"));
    }

    /**
     * 模板配置
     */
    protected static TemplateConfig.Builder templateConfig() {
        return new TemplateConfig.Builder()
                .disable(TemplateType.ENTITY)
                .entity("/templates/vm/entity.java")
                .service("/templates/vm/service.java")
                .serviceImpl("/templates/vm/serviceImpl.java")
                .mapper("/templates/vm/mapper.java")
                .xml("/templates/vm/mapper.xml")
                .controller("/templates/vm/controller.java");
    }

    /**
     * 注入配置
     */
    protected static InjectionConfig.Builder injectionConfig() {
        // 测试自定义输出文件之前注入操作，该操作再执行生成代码前 debug 查看
        return new InjectionConfig.Builder()
                .beforeOutputFile((tableInfo, objectMap) -> {
                    System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
                })
                // 这里是自定义传入模板参数值
                .customMap(Collections.singletonMap("datetime", DateTime.now()));
//                .customFile(new HashMap<String, String>() {{
//                    // 这里可以自定义自己的模板
//
//                }});
    }
}
